package csloader.requests
{
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.net.URLVariables;
	
	import csloader.events.EventDelegate;
	import csloader.events.ExtraEvent;
	import csloader.util.KeyValuePair;
	import csloader.util.RequestMethod;
	
	internal class RequestBase implements IRequest
	{
		//内部参数
		protected var loader:URLLoader;
		protected var completeDelegate:Function;
		protected var ioErrorDelegate:Function;	
		protected var callback:Function;
		
		public function RequestBase(callback:Function)
		{
			super();
			this.callback = callback;
		}
		
		public function getRequest(url:String, parms:KeyValuePair=null, requestMethod:String=RequestMethod.Get, ...args):URLRequest
		{
			var request:URLRequest = new URLRequest();
			request.method = requestMethod;
			if(requestMethod == RequestMethod.Get) {
				var qs:String = !parms?"":parms.toString();
				if(url.indexOf("?")<0 && qs!="") url += "?";
				request.url = url + qs;
			}
			else if (requestMethod == RequestMethod.Post) {
				if(parms && parms.length>0)
					request.data = new URLVariables(parms.toString());
				request.url = url;
			}
			return request;
		}
		
		public function sendRequest(request:URLRequest):void
		{
			loader = new URLLoader();
			loader.dataFormat = URLLoaderDataFormat.BINARY;
			completeDelegate = EventDelegate.create(completeHandler, request.url);
			loader.addEventListener(Event.COMPLETE, completeDelegate);
			ioErrorDelegate = EventDelegate.create(ioErrorHandler, request.url);
			loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorDelegate);
			try {
				loader.load(request);
			} catch (e:Error) {
				getResponse(request.url);		
				dispose();
			}
		}
		protected function completeHandler(e:Event, url:String):void {
			if(!loader.data) {
				getResponse(url);
			}
			else {
				var loader:URLLoader = URLLoader(e.target);
				getResponse(url, loader.data);
			}
			dispose();
		}
		
		protected function ioErrorHandler(e:IOErrorEvent, url:String):void {
			getResponse(url);
			dispose();
		}
		
		/**
		 * 处理响应的IO异常，无法被重写
		 * @param url
		 * @param response
		 * 
		 */
		public final function getResponse(url:String, response:*=null):void
		{
			//通讯错误，未能连接到服务器
			if(!response) {
				callback.apply(null, [new ExtraEvent(Event.COMPLETE, url)]);
				trace("与 " + url + " 通讯时发生网络错误。");
				return;
			}
			sendResponse(url, response);
		}
		
		/**
		 * 处理响应的格式异常
		 * @param url
		 * @param response
		 * 
		 */
		public function sendResponse(url:String, response:*=null):void
		{
			//数据正常返回
			callback.apply(null, [new ExtraEvent(Event.COMPLETE, url, response)]);
		}
		
		public function dispose():void
		{
			if(loader.hasEventListener(Event.COMPLETE))
				loader.removeEventListener(Event.COMPLETE,completeDelegate);
			if(loader.hasEventListener(IOErrorEvent.IO_ERROR))
				loader.removeEventListener(IOErrorEvent.IO_ERROR,ioErrorDelegate);		
		}
	}
}